// 获取containerEle元素
let containerEle = document.querySelector(".container");
/**
 * 写一个创建方块的抽象类
 * 抽象类的方法传入三个参数
 * x为绝对定位left值
 * y为绝对定位top值
 * color为方块的背景色
 * createRect方法为该对象原型上
 * 创建方块的方法
 */
 class Rect {
    constructor (x, y, color,type) {
        this.x = x;
	    this.y = y;
        this.color = color;
        this.type = type; 
        this.createRect();
    }
    /**
     * 在方块对象原型上定义一个创造方块的方法
     * 对象原型方法中创建一个div元素，名为rectEle
     * 该宽度为10px
     * 该高度为10px
     * 该元素定位属性为绝对定位
     * 该元素定位的left值为传入的x
     * 该元素定位的top值为传入的y
     * 该元素的背景色为传入的color
     * 该元素的border边框1px solid
     */
	createRect(){
        this.rectEle = document.createElement("div");
        this.rectEle.style.width = "10px";
        this.rectEle.style.height = "10px";
        this.rectEle.style.position = "absolute";
        this.rectEle.style.left = this.x + "px";
        this.rectEle.style.top = this.y + "px";
        this.rectEle.style.boxSizing = "border-box";
        this.rectEle.style.background = this.color;
        this.rectEle.style.border = "1px solid";
    }
}

/**
 * 创建一个实物类
 * 
*/
class Food {
    constructor(containerEle){
        this.containerEle = containerEle ; 
    }
    /**
     * 食物随机在框内产生
     * 
    */
    createFood(){
        let x = getRandom( parseInt(getStyle(containerEle, "width")) / 10 - 1,0) * 10 ;
        let y = getRandom( parseInt(getStyle(containerEle, "height")) / 10 - 1,0) * 10 ;
        let rect = new Rect( x , y , "yellow" , 'food');
        this.rect = rect ;
        rect.rectEle.style.boxSizing = "border-box";
        this.containerEle.appendChild(rect.rectEle);
    }
}
let food = new Food(containerEle);
class Snake {
    /**
     * 写一个蛇类的方法，该方法需要传入一个承载蛇的界面元素
     * 给蛇对象一个蛇身数组
     * 执行蛇对象创建蛇身的方法
     * 执行蛇对象渲染界面的方法
     *
     */
    constructor(containerEle){
        this.containerEle = containerEle;
        this.body = [];
        this.createBody();
        this.renderDom();
        this.snakeMove();
    }
    /**
     * 在蛇类的原型对象上写一个创建身体的方法createBody
     * 蛇长度为5
     * 身体为绿色，长度为4
     * 蛇头为红色，长度为1
     * 将每一个蛇身模块实例化
     * 并放入到蛇身数组中
     *
     */
    createBody(){
        for (let i = 0; i < 5; i++) {
            let rect;
            if (i == 4) {
                rect = new Rect(i * 10, 0, "red",'head');
            } else {
                rect = new Rect(i * 10, 0, "blue",'body');
            }
            this.body.push(rect);
        }
    }
    /**
     * 在蛇类的原型上创建一个渲染的方法
     * 遍历蛇对象的蛇身数组
     * 将数组中每一个div元素放到containerEle元素中
     */
    renderDom(){
        this.body.forEach((rect) => {
            this.containerEle.appendChild(rect.rectEle);
        });
    }
    snakeMove(){
        let that = this ; 
        let speed = 10;
        let direction = "left";
        document.onkeydown = function (event) {
            var e = event || window.event;
            var key = e.key;

            if (key == "ArrowUp") {
                direction = "top";
                speed = -Math.abs(speed);
            }
            if (key == "ArrowDown") {
                direction = "top";
                speed = Math.abs(speed);
            }
            if (key == "ArrowLeft") {
                direction = "left";
                speed = -Math.abs(speed);
            }
            if (key == "ArrowRight") {
                direction = "left";
                speed = Math.abs(speed);
            }
            
        };
        
        food.createFood();
        
        let timer = setInterval(function () {
            that.body.forEach((rect,key,arr) => {
                if ( rect.type == 'head' ){
                    rect.rectEle.style[direction] = parseInt( rect.rectEle.style[direction] ) + speed +'px';
                    let xx = parseInt( rect.rectEle.style.left ) ; 
                    let yy = parseInt( rect.rectEle.style.top ) ;
                    let y = parseInt( food.rect.rectEle.style.top ) ; 
                    let x = parseInt( food.rect.rectEle.style.left );
                
                    if ( xx < 0 || xx > that.containerEle.clientWidth - parseInt(rect.rectEle.style.width) 
                    || yy < 0 || yy > that.containerEle.clientHeight - parseInt(rect.rectEle.style.height) ){
                        clearTimeout(timer);
                        window.alert("你死了");
                    }   
                    arr.forEach((item,key)=>{
                        if( item.type == 'body' )
                        {
                            let xBody = parseInt( item.rectEle.style.left );
                            let yBody = parseInt( item.rectEle.style.top );
                        
                            if ( crash( xx , yy , xBody , yBody ) ){
                                clearTimeout(timer);
                                window.alert("你死了");
                            }
                        }
                    });
                    if ( crash( xx , yy , x , y ) ) {
                        food.rect.rectEle.style.display = 'none' ;
                        let rect = new Rect(-10,0,"blue","body");
                        snake.body.unshift(rect);
                        snake.renderDom();
                        food.createFood();
                    }
                } else {
                    rect.rectEle.style.top = arr[key+1].rectEle.style.top ; 
                    rect.rectEle.style.left = arr[key+1].rectEle.style.left ;
                }
            });
        }, 300);    
    }
}


// 创建一个蛇对象，然后实例化

let snake = new Snake(containerEle);

/**
 * 创建一个渲染界面背景的方法
 * 传入承载背景的元素
 * 调用创建背景的方法
 * */
class Background{
    constructor(containerEle){
        this.containerEle = containerEle;
	    this.createBackground();
    }
    /**
     * 在Background类的原型对象中写一个创建背景的方法
     * 调用获取非行间样式的函数
     * 获取承载背景元素的宽和高
     * 计算该盒子能放多少行，多少列元素
     * 实例化所有一个方块
     * 把方块的div元素的定位属性移除
     * 给方块的div元素加一个怪异盒子属性
     * 然后将方块的div元素加入到承载这些盒子的元素中
     */
    createBackground(){
        let x = parseInt(getStyle(containerEle, "width")) / 10;
		let y = parseInt(getStyle(containerEle, "height")) / 10;
		// console.log(x,y);
		for (let i = 0; i < x; i++) {
			for (let j = 0; j < y; j++) {
				let rect = new Rect( j * 10, i * 10, "#ccc", 'bGround' );
				rect.rectEle.style.position = "static" ;
				rect.rectEle.style.boxSizing = "border-box" ;
				this.containerEle.appendChild(rect.rectEle);
			}
		}
    }
}
/**
 * *
 * 实例化一个Background类的对象
 *
 */
let background = new Background(containerEle);

function getRandom(max,min){
    return parseInt( Math.random() * ( max - min + 1 ) + min );
}

function getStyle(ele, styleName) {
	if (window.getComputedStyle) {
		return getComputedStyle(ele, null)[styleName];
	} else {
		return ele.currentStyle[styleName];
	}
}

function crash( xx , yy , x , y ){
    if ( xx == x && yy ==y ){
        return true ; 
    } else {
        return false ;
    }
}